<template>
  <div class="environment-monitor">
    <div class="header-actions">
      <h1>漏洞验证过程监控</h1>
      <el-button type="primary" @click="selectTask">选择任务</el-button>
    </div>

    <!-- 验证状态卡片 -->
    <el-card>
      <template #header>
        <div class="card-header">
          <span>验证状态</span>
        </div>
      </template>

      <div class="verification-status">
        <el-steps :active="currentStepIndex" finish-status="success">
          <el-step title="任务开始" :description="formatTime(monitorData.startTime)" icon="video-play" />
          <el-step title="验证中" :description="formatTime(monitorData.verifyTime)" icon="loading" />
          <el-step title="等待完成" :description="monitorData.endTime ? formatTime(monitorData.endTime) : '--:--'" icon="check" />
        </el-steps>
      </div>
    </el-card>

    <!-- 资源使用监控 -->
    <div class="resource-monitor">
      <el-card>
        <template #header>
          <div class="card-header">
            <span>CPU 使用率</span>
            <span class="value-text">{{ monitorData.cpuUsage || '0' }}%</span>
          </div>
        </template>
        <div class="chart-container">
          <div ref="cpuChartRef" class="chart"></div>
        </div>
      </el-card>

      <el-card>
        <template #header>
          <div class="card-header">
            <span>内存使用率</span>
            <span class="value-text">{{ monitorData.memoryUsage || '0' }}%</span>
          </div>
        </template>
        <div class="chart-container">
          <div ref="memoryChartRef" class="chart"></div>
        </div>
      </el-card>
    </div>

    <!-- 网络流量监控 -->
    <el-card>
      <template #header>
        <div class="card-header">
          <span>网络流量</span>
        </div>
      </template>
      <div class="chart-container">
        <div ref="networkChartRef" class="chart network-chart"></div>
      </div>
    </el-card>

    <!-- 实时日志 -->
    <el-card>
      <template #header>
        <div class="card-header">
          <span>实时日志</span>
          <div class="log-actions">
            <el-dropdown @command="handleLogFilter">
              <el-button type="default" size="small">
                筛选 <el-icon class="el-icon--right"><arrow-down /></el-icon>
              </el-button>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item command="all">全部</el-dropdown-item>
                  <el-dropdown-item command="info">信息</el-dropdown-item>
                  <el-dropdown-item command="warning">警告</el-dropdown-item>
                  <el-dropdown-item command="error">错误</el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
            <el-button type="primary" size="small" @click="exportLogs">导出</el-button>
          </div>
        </div>
      </template>

      <div class="logs-container">
        <div v-for="(log, index) in filteredLogs" :key="index" class="log-item" :class="getLogClass(log.level)">
          <span class="log-time">{{ log.time }}</span>
          <span class="log-content">{{ log.content }}</span>
        </div>
        <div v-if="filteredLogs.length === 0" class="empty-logs">
          暂无日志记录
        </div>
      </div>
    </el-card>

    <!-- 任务选择对话框 -->
    <el-dialog v-model="taskDialogVisible" title="选择监控任务" width="30%">
      <el-form>
        <el-form-item label="选择任务">
          <el-select v-model="selectedTaskId" placeholder="请选择任务">
            <el-option
              v-for="task in taskOptions"
              :key="task.id"
              :label="task.name"
              :value="task.id"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="taskDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmSelectTask">确认</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed, onBeforeUnmount, watch } from 'vue'
import { useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'
import { ArrowDown } from '@element-plus/icons-vue'
import * as echarts from 'echarts/core'
import { LineChart } from 'echarts/charts'
import { TooltipComponent, GridComponent, LegendComponent } from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'
import { getVulnVerificationMonitor, getVulnVerificationLogs } from '@/api/vulnEnvironment'

// 注册必需的组件
echarts.use([LineChart, TooltipComponent, GridComponent, LegendComponent, CanvasRenderer])

const route = useRoute()

// 引用和状态
const cpuChartRef = ref(null)
const memoryChartRef = ref(null)
const networkChartRef = ref(null)
const cpuChart = ref(null)
const memoryChart = ref(null)
const networkChart = ref(null)
const taskDialogVisible = ref(false)
const selectedTaskId = ref('')
const logFilter = ref('all')
const monitorInterval = ref(null)
const logsInterval = ref(null)

// 任务选项
const taskOptions = ref([
  { id: '1', name: '漏洞验证任务-1' },
  { id: '2', name: '漏洞验证任务-2' },
  { id: '3', name: '漏洞验证任务-3' }
])

// 监控数据
const monitorData = reactive({
  startTime: '10:00:00',
  verifyTime: '10:00:30',
  endTime: null,
  status: 'running',
  cpuUsage: 78,
  memoryUsage: 42,
  networkTraffic: [],
  cpuData: Array(30).fill(0),
  memoryData: Array(30).fill(0),
  timeData: Array(30).fill('').map((_, i) => {
    const date = new Date()
    date.setSeconds(date.getSeconds() - (30 - i) * 10)
    return date.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit', second: '2-digit' })
  })
})

// 日志数据
const logs = ref([
  { time: '10:00:00', level: 'info', content: '启动验证进程' },
  { time: '10:00:01', level: 'info', content: '加载验证环境配置' },
  { time: '10:00:30', level: 'info', content: '开始执行漏洞验证' },
  { time: '10:00:45', level: 'warning', content: '检测到异常网络连接' },
  { time: '10:01:00', level: 'error', content: '目标端口无响应' }
])

// 过滤后的日志
const filteredLogs = computed(() => {
  if (logFilter.value === 'all') {
    return logs.value
  }
  return logs.value.filter(log => log.level === logFilter.value)
})

// 当前步骤索引
const currentStepIndex = computed(() => {
  if (monitorData.status === 'completed') return 2
  if (monitorData.verifyTime) return 1
  return 0
})

// 初始化图表
const initCharts = () => {
  // CPU 图表
  cpuChart.value = echarts.init(cpuChartRef.value)
  const cpuOption = {
    tooltip: {
      trigger: 'axis'
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: monitorData.timeData,
      boundaryGap: false
    },
    yAxis: {
      type: 'value',
      min: 0,
      max: 100,
      name: '%'
    },
    series: [{
      name: 'CPU',
      type: 'line',
      data: monitorData.cpuData,
      areaStyle: {
        color: {
          type: 'linear',
          x: 0,
          y: 0,
          x2: 0,
          y2: 1,
          colorStops: [{
            offset: 0,
            color: 'rgba(75, 192, 192, 0.8)'
          }, {
            offset: 1,
            color: 'rgba(75, 192, 192, 0.1)'
          }]
        }
      },
      itemStyle: {
        color: '#4bc0c0'
      },
      smooth: true
    }]
  }
  cpuChart.value.setOption(cpuOption)

  // 内存图表
  memoryChart.value = echarts.init(memoryChartRef.value)
  const memoryOption = {
    tooltip: {
      trigger: 'axis'
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: monitorData.timeData,
      boundaryGap: false
    },
    yAxis: {
      type: 'value',
      min: 0,
      max: 100,
      name: '%'
    },
    series: [{
      name: '内存',
      type: 'line',
      data: monitorData.memoryData,
      areaStyle: {
        color: {
          type: 'linear',
          x: 0,
          y: 0,
          x2: 0,
          y2: 1,
          colorStops: [{
            offset: 0,
            color: 'rgba(116, 119, 231, 0.8)'
          }, {
            offset: 1,
            color: 'rgba(116, 119, 231, 0.1)'
          }]
        }
      },
      itemStyle: {
        color: '#7477e7'
      },
      smooth: true
    }]
  }
  memoryChart.value.setOption(memoryOption)

  // 网络流量图表
  networkChart.value = echarts.init(networkChartRef.value)
  const networkOption = {
    tooltip: {
      trigger: 'axis'
    },
    legend: {
      data: ['上行', '下行']
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: monitorData.timeData
    },
    yAxis: {
      type: 'value',
      name: 'MB/s'
    },
    series: [
      {
        name: '上行',
        type: 'line',
        stack: 'Total',
        data: [0.5, 0.8, 1.2, 2.5, 2.8, 3.0, 3.8, 4.5, 5.0, 6.2, 4.8, 4.0, 3.5, 2.9, 3.5, 4.0, 4.5, 5.0, 5.5, 7.0, 6.8, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 1.5, 2.0, 2.5],
        areaStyle: {
          color: {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [{
              offset: 0,
              color: 'rgba(58, 184, 147, 0.8)'
            }, {
              offset: 1,
              color: 'rgba(58, 184, 147, 0.1)'
            }]
          }
        },
        itemStyle: {
          color: '#3ab893'
        },
        smooth: true
      },
      {
        name: '下行',
        type: 'line',
        stack: 'Total',
        data: [0.3, 0.5, 0.9, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 3.9, 3.5, 3.0, 2.5, 3.0, 3.5, 3.0, 4.0, 4.5, 5.0, 4.5, 4.0, 3.5, 3.0, 2.5, 2.0, 1.5, 0.9, 0.5, 0.3],
        areaStyle: {
          color: {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [{
              offset: 0,
              color: 'rgba(86, 152, 235, 0.8)'
            }, {
              offset: 1,
              color: 'rgba(86, 152, 235, 0.1)'
            }]
          }
        },
        itemStyle: {
          color: '#5698eb'
        },
        smooth: true
      }
    ]
  }
  networkChart.value.setOption(networkOption)

  // 窗口大小变化时重绘图表
  window.addEventListener('resize', handleResize)
}

// 处理窗口大小变化
const handleResize = () => {
  cpuChart.value && cpuChart.value.resize()
  memoryChart.value && memoryChart.value.resize()
  networkChart.value && networkChart.value.resize()
}

// 模拟数据更新
const updateMonitorData = async () => {
  try {
    // 实际应用中，这里应该从API获取实时数据
    // const { data } = await getVulnVerificationMonitor(selectedTaskId.value || route.params.id)
    
    // 模拟数据更新
    const now = new Date()
    const timeStr = now.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit', second: '2-digit' })
    
    // 更新时间数据
    monitorData.timeData.shift()
    monitorData.timeData.push(timeStr)
    
    // 更新CPU数据
    const newCpuValue = Math.floor(70 + Math.random() * 20)
    monitorData.cpuData.shift()
    monitorData.cpuData.push(newCpuValue)
    monitorData.cpuUsage = newCpuValue
    
    // 更新内存数据
    const newMemoryValue = Math.floor(35 + Math.random() * 15)
    monitorData.memoryData.shift()
    monitorData.memoryData.push(newMemoryValue)
    monitorData.memoryUsage = newMemoryValue
    
    // 更新图表
    if (cpuChart.value) {
      cpuChart.value.setOption({
        xAxis: {
          data: monitorData.timeData
        },
        series: [{
          data: monitorData.cpuData
        }]
      })
    }
    
    if (memoryChart.value) {
      memoryChart.value.setOption({
        xAxis: {
          data: monitorData.timeData
        },
        series: [{
          data: monitorData.memoryData
        }]
      })
    }
    
    if (networkChart.value) {
      const upData = []
      const downData = []
      for (let i = 0; i < 30; i++) {
        upData.push((Math.random() * 5 + 2).toFixed(1))
        downData.push((Math.random() * 4 + 1).toFixed(1))
      }
      
      networkChart.value.setOption({
        xAxis: {
          data: monitorData.timeData
        },
        series: [
          {
            data: upData
          },
          {
            data: downData
          }
        ]
      })
    }
  } catch (error) {
    console.error('获取监控数据失败', error)
  }
}

// 拉取日志数据
const fetchLogs = async () => {
  try {
    // 实际应用中，这里应该从API获取实时日志
    // const { data } = await getVulnVerificationLogs(selectedTaskId.value || route.params.id)
    // logs.value = data
    
    // 模拟随机添加一条日志
    if (Math.random() > 0.7) {
      const now = new Date()
      const timeStr = now.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit', second: '2-digit' })
      const levels = ['info', 'warning', 'error']
      const level = levels[Math.floor(Math.random() * levels.length)]
      const contents = [
        '检查系统服务状态',
        '扫描目标端口',
        '尝试建立连接',
        '发送测试数据包',
        '检测到异常响应',
        '目标系统无响应',
        '连接被重置',
        '验证攻击向量',
        '漏洞利用成功',
        '目标系统崩溃'
      ]
      const content = contents[Math.floor(Math.random() * contents.length)]
      
      logs.value.push({
        time: timeStr,
        level,
        content
      })
      
      // 保持日志不超过100条
      if (logs.value.length > 100) {
        logs.value.shift()
      }
    }
  } catch (error) {
    console.error('获取日志失败', error)
  }
}

// 格式化时间
const formatTime = (timeStr) => {
  return timeStr || '--:--'
}

// 获取日志样式类
const getLogClass = (level) => {
  return {
    'log-info': level === 'info',
    'log-warning': level === 'warning',
    'log-error': level === 'error'
  }
}

// 处理日志过滤
const handleLogFilter = (command) => {
  logFilter.value = command
}

// 打开任务选择对话框
const selectTask = () => {
  taskDialogVisible.value = true
}

// 确认选择任务
const confirmSelectTask = () => {
  if (!selectedTaskId.value) {
    ElMessage.warning('请选择任务')
    return
  }
  
  taskDialogVisible.value = false
  ElMessage.success('任务切换成功')
  // 重新加载任务数据
  fetchMonitorData()
  fetchLogs()
}

// 导出日志
const exportLogs = () => {
  // 导出日志逻辑
  ElMessage.success('日志导出成功')
}

// 获取监控数据
const fetchMonitorData = () => {
  // 实际应用中，这里应该从API获取初始数据
  updateMonitorData()
}

// 初始化定时更新
const initIntervals = () => {
  // 清除可能存在的旧定时器
  clearIntervals()
  
  // 每5秒更新一次监控数据
  monitorInterval.value = setInterval(updateMonitorData, 5000)
  
  // 每3秒更新一次日志
  logsInterval.value = setInterval(fetchLogs, 3000)
}

// 清除定时器
const clearIntervals = () => {
  if (monitorInterval.value) {
    clearInterval(monitorInterval.value)
    monitorInterval.value = null
  }
  
  if (logsInterval.value) {
    clearInterval(logsInterval.value)
    logsInterval.value = null
  }
}

// 组件挂载时初始化
onMounted(() => {
  // 从路由获取任务ID
  if (route.params.id) {
    selectedTaskId.value = route.params.id
  }
  
  // 初始化图表和数据
  initCharts()
  fetchMonitorData()
  fetchLogs()
  initIntervals()
})

// 组件卸载前清理
onBeforeUnmount(() => {
  clearIntervals()
  window.removeEventListener('resize', handleResize)
  
  // 销毁图表实例
  cpuChart.value && cpuChart.value.dispose()
  memoryChart.value && memoryChart.value.dispose()
  networkChart.value && networkChart.value.dispose()
})
</script>

<style lang="scss" scoped>
.environment-monitor {
  padding: 20px;
  
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    
    .value-text {
      font-size: 16px;
      font-weight: bold;
    }
  }
  
  .verification-status {
    padding: 10px 0;
  }
  
  .chart-container {
    width: 100%;
    
    .chart {
      height: 250px;
      width: 100%;
    }
    
    .network-chart {
      height: 300px;
    }
  }
  
  .logs-container {
    height: 300px;
    overflow-y: auto;
    font-family: monospace;
    
    .log-item {
      padding: 4px 8px;
      border-bottom: 1px solid #f0f0f0;
      font-size: 13px;
      display: flex;
      
      .log-time {
        color: #909399;
        width: 80px;
        flex-shrink: 0;
      }
      
      .log-content {
        flex: 1;
      }
      
      &.log-info {
        color: #606266;
      }
      
      &.log-warning {
        color: #e6a23c;
        background-color: rgba(230, 162, 60, 0.05);
      }
      
      &.log-error {
        color: #f56c6c;
        background-color: rgba(245, 108, 108, 0.05);
      }
    }
    
    .empty-logs {
      text-align: center;
      color: #909399;
      padding: 40px 0;
    }
  }
}
</style> 